package com.terren.webdig.basic.impl;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Repository;

import com.terren.webdig.basic.BasicEntity;
import com.terren.webdig.basic.IBasicDaoSupport;
import com.terren.webdig.common.dbsource.DBSourceManager;
import com.terren.webdig.common.dbsource.DataSourceHandle;

/**
 * 主要的 dao 类
 * 
 * @author Administrator
 * 
 */
@Repository("basicDaoSupport")
public class BasicDaoSupportImpl extends SqlSessionDaoSupport implements IBasicDaoSupport {
	/**
	 * mybatis-spring-1.2.x.jar 版本的 sqlSessionTemplate 注入有所改动，必须重写次方法
	 */
	@Autowired
	public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
		super.setSqlSessionTemplate(sqlSessionTemplate);
	}

	protected <S> S getMapper(Class<S> clazz) {
		return getSqlSession().getMapper(clazz);
	}

	public Object delete(String sql, Object obj) throws Exception {
		logger.info("delete[" + sql + "]");
		SqlSession session = null;
		Object object = null;
		try {
			session = this.getSqlSession();
			setDataSourceType(obj);
			object = session.delete(sql, obj);
		} catch (Exception e) {
			throw e;
		} finally {
			DBSourceManager.setDefaultDB();
			logger.info("datasource[:" + DataSourceHandle.getDataSourceType() + "]");
		}
		return object;
	}

	public Object deleteBatch(String sql, Object[] obj) throws Exception {
		return null;
	}

	public Object deleteBatch(String sql, List<Object> list) throws Exception {
		return null;
	}

	public Object findForList(String sql, Object obj) throws Exception {
		logger.info("findForList[" + sql + "]");
		SqlSession session = null;
		Object object = null;
		try {
			session = this.getSqlSession();
			setDataSourceType(obj);
			object = session.selectList(sql, obj);
		} catch (Exception e) {
			throw e;
		} finally {
			DBSourceManager.setDefaultDB();
			logger.info("datasource[:" + DataSourceHandle.getDataSourceType() + "]");
		}
		return object;
	}

	public Object findForMap(String sql, Object obj, String key, String value) throws Exception {
		return null;
	}

	public Object findForObject(String sql, Object obj) throws Exception {
		logger.info("findForObject[" + sql + "]");
		SqlSession session = null;
		Object object = null;
		try {
			session = this.getSqlSession();
			setDataSourceType(obj);
			object = session.selectOne(sql, obj);
		} catch (Exception e) {
			throw e;
		} finally {
			DBSourceManager.setDefaultDB();
			logger.info("datasource[:" + DataSourceHandle.getDataSourceType() + "]");
		}
		return object;
	}

	public long getcount(String sql, Object obj) throws Exception {
		return 0;
	}

	public Object save(String sql, Object paramObj) throws DuplicateKeyException, Exception {
		logger.info("save[" + sql + "]");
		SqlSession session = null;
		Object object = null;
		try {
			session = this.getSqlSession();
			setDataSourceType(paramObj);
			object = session.insert(sql, paramObj);
		} catch (DuplicateKeyException e) {
			throw e;
		} catch (Exception e) {
			throw e;
		} finally {
			DBSourceManager.setDefaultDB();
			logger.info("datasource[:" + DataSourceHandle.getDataSourceType() + "]");
		}
		return object;
	}

	public int saveList(String sql, List<?> list) throws Exception {
		int count = 0;
		try {
			for (Object entity : list) {
				count += getSqlSession().insert(sql, entity);
			}
		} catch (Exception e) {
			e.printStackTrace();
			count = -1;
		}
		return count;
	}

	public Object saveBatch(String sql, List<Object> list) throws Exception {

		return null;
	}

	public Object update(String sql, Object obj) throws Exception {
		logger.info("update[" + sql + "]");
		SqlSession session = null;
		Object object = null;
		try {
			session = this.getSqlSession();
			setDataSourceType(obj);
			object = session.update(sql, obj);
		} catch (Exception e) {
			throw e;
		} finally {
			DBSourceManager.setDefaultDB();
			logger.info("datasource[:" + DataSourceHandle.getDataSourceType() + "]");
		}
		return object;
	}

	public Object updateBatch(String sql, List<Object> list) throws Exception {
		return null;
	}

	public Object updateBatch(String sql, Object[] obj) throws Exception {
		return null;
	}

	// 自动注入数据源类型
	public void setDataSourceType(Object entity) {
		if (entity instanceof BasicEntity) {
			setEntityType(entity);
			return;
		}
		if (entity instanceof Map<?, ?>) {
			Map<?, ?> map = (Map<?, ?>) entity;
			if (map.containsKey("dbType")) {
				if (map.get("dbType").equals(DBSourceManager.webdigDBSource)) {
					DBSourceManager.setWebdigDB();
				} else if (map.get("dbType").equals(DBSourceManager.newsDBSource)) {
					DBSourceManager.setNewsDB();
				} 
			} else {
				DBSourceManager.setDefaultDB();
			}
			logger.info("datasource[:" + DataSourceHandle.getDataSourceType() + "]");
			return;
		}
		if (entity instanceof List<?>) {
			List<?> list = (List<?>) entity;
			if (list.size() > 0) {
				Object object = list.get(0);
				if (object instanceof BasicEntity) {
					setEntityType(object);
				}
			}
		}
	}

	public void setEntityType(Object entity) {
		BasicEntity basicEntity = (BasicEntity) entity;
		if (basicEntity.getDbType() != null) {
			if (basicEntity.getDbType().equals(DBSourceManager.webdigDBSource)) {
				DBSourceManager.setWebdigDB();
			} else if (basicEntity.getDbType().equals(DBSourceManager.newsDBSource)) {
				DBSourceManager.setNewsDB();
			} 
		} else {
			DBSourceManager.setDefaultDB();
		}
		logger.info("datasource[:" + DataSourceHandle.getDataSourceType() + "]");
	}
}
